import { component$ } from '@builder.io/qwik';
import { Form, routeAction$, routeLoader$, zod$ } from '@builder.io/qwik-city';
import Button from '~/components/ui/Button';
import Input from '~/components/ui/Input';
import { z } from 'zod';
import { authenticate, checkAuth } from '~/server/authn';
import { db } from '~/server/db';
import { pw } from '~/server/pw';
import Card, { CardBody, CardTitle } from '~/components/ui/Card';
import _ from 'lodash';
import logger from '~/server/logger';
import { userAccountService } from '~/server/service/user-account-service';
import { userPasswordService } from '~/server/service/user-password-service';

export const useLoader = routeLoader$(async (requestEvent) => {
  const auth = await checkAuth(requestEvent);
  if (auth.ok) {
    throw requestEvent.redirect(307, '/me');
  }
});

export const useLoginAction = routeAction$(
  async (props, requestEvent) => {
    const auth = await checkAuth(requestEvent);
    if (auth.ok) {
      throw requestEvent.redirect(307, '/me');
    }

    const { phone, password } = props;

    const userAccount = await userAccountService.findByPhone(db, phone);
    if (!userAccount) return requestEvent.error(400, '手机号或密码错误。');
    if (userAccount.locked) return requestEvent.error(400, '账户已被锁定。');
    if (userAccount.disabled) return requestEvent.error(400, '账户已被禁用。');

    const userPassword = await userPasswordService.findByUserId(db, userAccount.userId);
    if (!userPassword) return requestEvent.error(400, '手机号或密码错误。');

    const verified = await pw.verify(userPassword.encryptedPassword, password);
    if (!verified) return requestEvent.error(400, '手机号或密码错误。');

    await authenticate(requestEvent.cookie, userAccount.userId);
    logger.info('[login]', { userId: userAccount.userId.toString() });

    throw requestEvent.redirect(307, '/me'); // TODO: 登录后回到原来的页面
  },
  zod$(
    z.object({
      phone: z.string().regex(/^1[3-9]\d{9}$/, { message: '手机号格式错误。' }),
      password: z
        .string()
        .min(10, { message: '密码至少应该包含 10 个字符。' })
        .max(36, { message: '密码不可超过 36 个字符' }),
    })
  )
);

function ErrorMessage({ message }: { message: string | null | undefined }) {
  if (!message) return null;
  return <div class="text-red-500 text-sm font-bold">{message}</div>;
}

export default component$(() => {
  const loginAction = useLoginAction();

  const fieldErrors = loginAction.value?.fieldErrors;
  const phoneErrors = fieldErrors?.phone || [];
  const passwordErrors = fieldErrors?.password || [];

  return (
    <div style={{ maxWidth: 360 }} class="mx-auto mt-40">
      <Card>
        <CardTitle>登录</CardTitle>
        <CardBody class="py-4">
          <Form action={loginAction}>
            <div>
              <Input name="phone" placeholder="请输入手机号" autocomplete="new-password" block class="my-4" />
              <ErrorMessage message={_.first(phoneErrors)} />
            </div>
            <div>
              <Input
                name="password"
                placeholder="请输入密码"
                autocomplete="new-password"
                block
                type="password"
                class="my-4"
              />
              <ErrorMessage message={_.first(passwordErrors)} />
            </div>
            <ErrorMessage message={loginAction.value?.message} />
            <div>
              <Button type="submit" varient="primary" block class="my-4">
                登录
              </Button>
            </div>
          </Form>
        </CardBody>
      </Card>
    </div>
  );
});
